/**********************************************************************************************************
** 驱动文件：	ups-SNHXXX.c
** 驱动类型：	ups
** 设备名称：	UPS监测
** 设备型号：	SNHXXX
** 设备品牌：	赛能
** 设备协议：	RS232通讯协议
** 驱动描述：	适用于SNH系列三进单出高频在线式UPS，具备完善的检测、保护功能;体积小、重量轻、工作效率高。协议指令为QGS、QWS、QMOD
** 生成日期：	2020-04-29 18:30:14
**********************************************************************************************************/
#include "Includes.h"


/**********************************************************************************************************
* 定义设备数据点变量结构
**********************************************************************************************************/
typedef struct{
	Var UPSMode;								//UPS模式
	Var InputVoltage;							//输入电压
	Var InputFrequency;							//输入频率
	Var OutputVoltage;							//输出电压
	Var OutputFrequency;						//输出频率
	Var OutputCurrent;							//输出电流
	Var OutputLoadPercent;						//输出负载率
	Var PositiveBUSVoltage;						//正极母线电压
	Var NegativeBUSVoltage;						//负极母线电压
	Var PositiveBatteryVoltage;					//正极电池组电压
	Var NegativeBatteryVoltage;					//负极电池组电压
	Var RunStatus;								//运行状态
	Var UtilityFail;							//市电故障
	Var BatteryLowStatus;						//电池低压状态
	Var BypassActive;							//旁路激活
	Var UPSFailed;								//UPS故障
	Var TestInProgress;							//测试进行
	Var ShutdownActive;							//关机激活
	Var BatteryOpen;							//电池未接报警
	Var IPNloss;								//输入N线丢失
	Var IPSiteFail;								//输入零火反接
	Var LinePhaseError;							//市电相序错误
	Var BypassPhaseError;						//旁路相序错误
	Var BatteryOverCharge;						//电池过冲
	Var BatteryLow;								//电池低压
	Var OverloadWarning;						//过载报警
	Var FanFail;								//风扇故障
	Var EPOActive;								//EPO生效
	Var OverTemperature;						//高温报警
	Var ChargerFail;							//充电器故障
	Var L1IPFuseFail;							//L1输入保险开路
	Var L2IPFuseFail;							//L2输入保险开路
	Var L3IPFuseFail;							//L3输入保险开路
	Var CANCommunicationError;					//CAN总线通讯报警
	Var BatteryFuseBroken;						//电池保险开路
	Var P1CutOffPreAlarm;						//P1切断预警
	Var BatteryReplaceWarn;						//电池更换告警
	Var MaintainBypassSwitchOffAlarm;			//维修旁路开路报警
	Var MainsFailure;							//市电异常
	Var BypassUnstable;							//旁路异常
	Var BatteryDischargerOverly;				//电池过放报警
}Data_Struct;									//定义变量结构


/**********************************************************************************************************
* 设备数据点变量属性声明
**********************************************************************************************************/
const static Var_Property_Def var_attr[] = {
	{
		OCTSTR,
		0,
		READONLY,
		"UPSMode",
		"UPS模式",
		"",
		"UPS模式：0-初始化；1-待机状态；2-旁路状态；3-市电状态；4-电池状态；5-电池自检状态；6-逆变模式；7-经济模式；8-关机模式；9-故障模式",
		0,
		0,
		"",
		"",
		0,
		0
	},
	{
		FLOAT,
		0,
		READONLY,
		"InputVoltage",
		"输入电压",
		"V",
		"输入电压",
		0,
		0,
		"输入相电压过高",
		"输入相电压过低",
		0,
		0
	},
	{
		FLOAT,
		0,
		READONLY,
		"InputFrequency",
		"输入频率",
		"Hz",
		"输入频率",
		0,
		0,
		"输入频率过高",
		"输入频率过低",
		0,
		0
	},
	{
		FLOAT,
		0,
		READONLY,
		"OutputVoltage",
		"输出电压",
		"V",
		"输出电压",
		0,
		0,
		"输出电压过高",
		"输出电压过低",
		0,
		0
	},
	{
		FLOAT,
		0,
		READONLY,
		"OutputFrequency",
		"输出频率",
		"Hz",
		"输出频率",
		0,
		0,
		"输出频率过高",
		"输出频率过低",
		0,
		0
	},
	{
		FLOAT,
		0,
		READONLY,
		"OutputCurrent",
		"输出电流",
		"A",
		"输出电流",
		0,
		0,
		"输出电流过高",
		"输出电流过低",
		0,
		0
	},
	{
		INTEGER,
		0,
		READONLY,
		"OutputLoadPercent",
		"输出负载率",
		"%",
		"输出负载率",
		0,
		0,
		"输出负载率过高",
		"输出负载率过低",
		0,
		0
	},
	{
		FLOAT,
		0,
		READONLY,
		"PositiveBUSVoltage",
		"正极母线电压",
		"V",
		"正极母线电压",
		0,
		0,
		"正极母线电压过高",
		"正极母线电压过低",
		0,
		0
	},
	{
		FLOAT,
		0,
		READONLY,
		"NegativeBUSVoltage",
		"负极母线电压",
		"V",
		"负极母线电压",
		0,
		0,
		"负极母线电压过高",
		"负极母线电压过低",
		0,
		0
	},
	{
		FLOAT,
		0,
		READONLY,
		"PositiveBatteryVoltage",
		"正极电池组电压",
		"V",
		"正极电池组电压",
		0,
		0,
		"正极电池组电压过高",
		"正极电池组电压过低",
		0,
		0
	},
	{
		FLOAT,
		0,
		READONLY,
		"NegativeBatteryVoltage",
		"负极电池组电压",
		"V",
		"负极电池组电压",
		0,
		0,
		"负极电池组电压过高",
		"负极电池组电压过低",
		0,
		0
	},
	{
		OCTSTR,
		0,
		READONLY,
		"RunStatus",
		"运行状态",
		"",
		"运行状态：0-待机状态；1-在线互动、2-在线状态",
		0,
		0,
		"",
		"",
		0,
		0
	},
	{
		OCTSTR,
		0,
		READONLY,
		"UtilityFail",
		"市电故障",
		"",
		"市电故障",
		0,
		0,
		"故障",
		"",
		0,
		0
	},
	{
		OCTSTR,
		0,
		READONLY,
		"BatteryLowStatus",
		"电池低压状态",
		"",
		"电池低压",
		0,
		0,
		"告警",
		"",
		0,
		0
	},
	{
		OCTSTR,
		0,
		READONLY,
		"BypassActive",
		"旁路激活",
		"",
		"旁路激活",
		0,
		0,
		"告警",
		"",
		0,
		0
	},
	{
		OCTSTR,
		0,
		READONLY,
		"UPSFailed",
		"UPS故障",
		"",
		"UPS故障",
		0,
		0,
		"故障",
		"",
		0.000,
		0.000
	},
	{
		OCTSTR,
		0,
		READONLY,
		"TestInProgress",
		"测试进行",
		"",
		"测试进行",
		0,
		0,
		"",
		"",
		0,
		0
	},
	{
		OCTSTR,
		0,
		READONLY,
		"ShutdownActive",
		"关机激活",
		"",
		"关机激活",
		0,
		0,
		"告警",
		"",
		0,
		0
	},
	{
		OCTSTR,
		0,
		READONLY,
		"BatteryOpen",
		"电池未接报警",
		"",
		"电池未接报警",
		0,
		0,
		"报警",
		"",
		0,
		0
	},
	{
		OCTSTR,
		0,
		READONLY,
		"IPNloss",
		"输入N线丢失",
		"",
		"输入N线丢失",
		0,
		0,
		"报警",
		"",
		0,
		0
	},
	{
		OCTSTR,
		0,
		READONLY,
		"IPSiteFail",
		"输入零火反接",
		"",
		"输入零火线反接报警",
		0,
		0,
		"报警",
		"",
		0,
		0
	},
	{
		OCTSTR,
		0,
		READONLY,
		"LinePhaseError",
		"市电相序错误",
		"",
		"市电相序错误",
		0,
		0,
		"报警",
		"",
		0,
		0
	},
	{
		OCTSTR,
		0,
		READONLY,
		"BypassPhaseError",
		"旁路相序错误",
		"",
		"旁路相序错误",
		0,
		0,
		"报警",
		"",
		0,
		0
	},
	{
		OCTSTR,
		0,
		READONLY,
		"BatteryOverCharge",
		"电池过冲",
		"",
		"电池过冲报警",
		0,
		0,
		"报警",
		"",
		0,
		0
	},
	{
		OCTSTR,
		0,
		READONLY,
		"BatteryLow",
		"电池低压",
		"",
		"电池低压报警",
		0,
		0,
		"报警",
		"",
		0,
		0
	},
	{
		OCTSTR,
		0,
		READONLY,
		"OverloadWarning",
		"过载报警",
		"",
		"过载报警",
		0,
		0,
		"报警",
		"",
		0,
		0
	},
	{
		OCTSTR,
		0,
		READONLY,
		"FanFail",
		"风扇故障",
		"",
		"风扇模组堵转报警",
		0,
		0,
		"报警",
		"",
		0,
		0
	},
	{
		OCTSTR,
		0,
		READONLY,
		"EPOActive",
		"EPO生效",
		"",
		"EPO开关生效",
		0,
		0,
		"报警",
		"",
		0,
		0
	},
	{
		OCTSTR,
		0,
		READONLY,
		"OverTemperature",
		"高温报警",
		"",
		"高温报警",
		0,
		0,
		"报警",
		"",
		0,
		0
	},
	{
		OCTSTR,
		0,
		READONLY,
		"ChargerFail",
		"充电器故障",
		"",
		"充电器报警",
		0,
		0,
		"报警",
		"",
		0,
		0
	},
	{
		OCTSTR,
		0,
		READONLY,
		"L1IPFuseFail",
		"L1输入保险开路",
		"",
		"L1输入保险开路报警",
		0,
		0,
		"报警",
		"",
		0,
		0
	},
	{
		OCTSTR,
		0,
		READONLY,
		"L2IPFuseFail",
		"L2输入保险开路",
		"",
		"L2输入保险开路报警",
		0,
		0,
		"报警",
		"",
		0,
		0
	},
	{
		OCTSTR,
		0,
		READONLY,
		"L3IPFuseFail",
		"L3输入保险开路",
		"",
		"L3输入保险开路报警",
		0,
		0,
		"报警",
		"",
		0,
		0
	},
	{
		OCTSTR,
		0,
		READONLY,
		"CANCommunicationError",
		"CAN总线通讯报警",
		"",
		"CAN总线通讯报警",
		0,
		0,
		"报警",
		"",
		0,
		0
	},
	{
		OCTSTR,
		0,
		READONLY,
		"BatteryFuseBroken",
		"电池保险开路",
		"",
		"电池保险开路报警",
		0,
		0,
		"报警",
		"",
		0,
		0
	},
	{
		OCTSTR,
		0,
		READONLY,
		"P1CutOffPreAlarm",
		"P1切断预警",
		"",
		"P1切断预警",
		0,
		0,
		"预警",
		"",
		0,
		0
	},
	{
		OCTSTR,
		0,
		READONLY,
		"BatteryReplaceWarn",
		"电池更换告警",
		"",
		"电池需要更换告警",
		0,
		0,
		"告警",
		"",
		0,
		0
	},
	{
		OCTSTR,
		0,
		READONLY,
		"MaintainBypassSwitchOffAlarm",
		"维修旁路开路报警",
		"",
		"维修旁路开路报警",
		0,
		0,
		"报警",
		"",
		0,
		0
	},
	{
		OCTSTR,
		0,
		READONLY,
		"MainsFailure",
		"市电异常",
		"",
		"市电电压极度不稳定",
		0,
		0,
		"报警",
		"",
		0,
		0
	},
	{
		OCTSTR,
		0,
		READONLY,
		"BypassUnstable",
		"旁路异常",
		"",
		"旁路状态不稳定",
		0,
		0,
		"报警",
		"",
		0,
		0
	},
	{
		OCTSTR,
		0,
		READONLY,
		"BatteryDischargerOverly",
		"电池过放报警",
		"",
		"电池过放报警",
		0,
		0,
		"报警",
		"",
		0,
		0
	}
};


/**********************************************************************************************************
* 函数名称： static void cmd_fun(short index, int addr, void *data, char *cmd, short *len)
* 函数说明： 生成获取传感器数据指令
* 输入参数： 指令索引，传感器地址，变量结构体指针,以及指令缓存区指针,指令长度
* 返回参数： 无
**********************************************************************************************************/
static void cmd_fun(short index, int addr, void *data, char *cmd, short *len)
{
	switch(index)
	{
		case 0:
			*len = sprintf(cmd,"QMOD\r");
			break;
		case 1:
			*len = sprintf(cmd,"QGS\r");
			break;
		case 2:
			*len = sprintf(cmd,"QWS\r");
			break;			
		default:
			break;
	}
}


/**********************************************************************************************************
* 函数名称： static int parse_fun(short index, int addr, void *data, char *buf, short len)
* 函数说明： 解析传感器响应的数据，并写入数据库
* 输入参数： 解析索引,传感器地址，变量结构体指针，以及响应数据缓存取指针，响应数据长度
* 返回参数： 返回解析结果，返回0成功，返回1失败
**********************************************************************************************************/
static int parse_fun(short index, int addr, void *data, char *buf, short len)
{
	Data_Struct 	*d = (Data_Struct*)data;

	buf[len] = '\0';
	if(buf!=NULL && buf[0]=='(' && len>0 && buf[len-1]=='\r')
	{	
		switch(index)
		{
			case 0:		//(M<cr>
				switch(buf[1]){
					case 'P': d->UPSMode.value.str = "初始化";		Set_Var_Status(&d->UPSMode, Normal, NULL) ;break;
					case 'S': d->UPSMode.value.str = "待机状态";	Set_Var_Status(&d->UPSMode, Normal, NULL) ;break;
					case 'Y': d->UPSMode.value.str = "旁路状态";	Set_Var_Status(&d->UPSMode, Normal, NULL) ;break;
					case 'L': d->UPSMode.value.str = "市电状态";	Set_Var_Status(&d->UPSMode, Normal, NULL) ;break;
					case 'B': d->UPSMode.value.str = "电池状态";	Set_Var_Status(&d->UPSMode, Normal, NULL) ;break;
					case 'T': d->UPSMode.value.str = "电池自检状态";Set_Var_Status(&d->UPSMode, Normal, NULL) ;break;
					case 'C': d->UPSMode.value.str = "逆变模式";	Set_Var_Status(&d->UPSMode, Normal, NULL) ;break;
					case 'E': d->UPSMode.value.str = "经济模式";	Set_Var_Status(&d->UPSMode, Normal, NULL) ;break;
					case 'D': d->UPSMode.value.str = "关机模式";	Set_Var_Status(&d->UPSMode, Alarm, NULL) ;break;
					case 'F': d->UPSMode.value.str = "故障模式";	Set_Var_Status(&d->UPSMode, Alarm, NULL) ;break;
					default: break;
				}
				break;
			case 1:		//(231.3 50.0 220.1 50.0 009.8 005 367.2 369.3 214.6 214.4 002.8 100000000000
				d->InputVoltage.value.fnum			= atof(buf+1);
				d->InputFrequency.value.fnum 		= atof(buf+7);
				d->OutputVoltage.value.fnum 		= atof(buf+12);	
				d->OutputFrequency.value.fnum 		= atof(buf+18);
				d->OutputCurrent.value.fnum 		= atof(buf+23);
				d->OutputLoadPercent.value.inum 	= atoi(buf+29);	
				d->PositiveBUSVoltage.value.fnum 	= atof(buf+33);
				d->NegativeBUSVoltage.value.fnum 	= atof(buf+39);
				d->PositiveBatteryVoltage.value.fnum= atof(buf+45);	
				d->NegativeBatteryVoltage.value.fnum= atof(buf+51);

				if(buf[63]=='0' && buf[64]=='0'){
					d->RunStatus.value.str			= "待机状态";
					Set_Var_Status(&d->RunStatus,	Alarm, NULL);
				}
				else if(buf[63]=='0' && buf[64]=='1'){
					d->RunStatus.value.str			= "在线互动";
					Set_Var_Status(&d->RunStatus,	Normal, NULL);
				}
				else if(buf[63]=='1' && buf[64]=='0'){
					d->RunStatus.value.str			= "在线状态";
					Set_Var_Status(&d->RunStatus,	Normal, NULL);
				}
				else{
					d->RunStatus.value.str			= "未知";
					Set_Var_Status(&d->RunStatus,	Unknown, NULL);					
				}

				d->UtilityFail.value.str			= buf[65]=='1'?"告警":"正常";
				Set_Var_Status(&d->UtilityFail,		  buf[65]=='1'?Alarm:Normal, NULL);						
				d->BatteryLowStatus.value.str		= buf[66]=='1'?"告警":"正常";
				Set_Var_Status(&d->BatteryLowStatus,  buf[66]=='1'?Alarm:Normal, NULL);						
				d->BypassActive.value.str			= buf[67]=='1'?"告警":"正常";
				Set_Var_Status(&d->BypassActive,	  buf[67]=='1'?Alarm:Normal, NULL);						
				d->UPSFailed.value.str				= buf[68]=='1'?"告警":"正常";				
				Set_Var_Status(&d->UPSFailed,		  buf[68]=='1'?Alarm:Normal, NULL);	
				d->TestInProgress.value.str			= buf[70]=='1'?"告警":"正常";
				Set_Var_Status(&d->TestInProgress,	  buf[70]=='1'?Alarm:Normal, NULL);						
				d->ShutdownActive.value.str			= buf[71]=='1'?"告警":"正常";
				Set_Var_Status(&d->ShutdownActive,	  buf[71]=='1'?Alarm:Normal, NULL);	
				break;
			case 2:	//(a0a1……a62a63<cr>
				d->BatteryOpen.value.str						= buf[1]=='1'?"告警":"正常";
				Set_Var_Status(&d->BatteryOpen,			  		  buf[1]=='1'?Alarm:Normal, NULL);
				d->IPNloss.value.str							= buf[2]=='1'?"告警":"正常";
				Set_Var_Status(&d->IPNloss,		  				  buf[2]=='1'?Alarm:Normal, NULL);
				d->IPSiteFail.value.str							= buf[3]=='1'?"告警":"正常";
				Set_Var_Status(&d->IPSiteFail,		 	 		  buf[3]=='1'?Alarm:Normal, NULL);
				d->LinePhaseError.value.str						= buf[4]=='1'?"告警":"正常";
				Set_Var_Status(&d->LinePhaseError,		  		  buf[4]=='1'?Alarm:Normal, NULL);
				d->BypassPhaseError.value.str					= buf[5]=='1'?"告警":"正常";
				Set_Var_Status(&d->BypassPhaseError,		  	  buf[5]=='1'?Alarm:Normal, NULL);
				d->BatteryOverCharge.value.str					= buf[7]=='1'?"告警":"正常";
				Set_Var_Status(&d->BatteryOverCharge,		  	  buf[7]=='1'?Alarm:Normal, NULL);
				d->BatteryLow.value.str							= buf[8]=='1'?"告警":"正常";
				Set_Var_Status(&d->BatteryLow,		  			  buf[8]=='1'?Alarm:Normal, NULL);
				d->OverloadWarning.value.str					= buf[9]=='1'?"告警":"正常";
				Set_Var_Status(&d->OverloadWarning,		  		  buf[9]=='1'?Alarm:Normal, NULL);
				d->FanFail.value.str							= buf[10]=='1'?"告警":"正常";
				Set_Var_Status(&d->FanFail,		  				  buf[10]=='1'?Alarm:Normal, NULL);
				d->EPOActive.value.str							= buf[11]=='1'?"告警":"正常";
				Set_Var_Status(&d->EPOActive,		  			  buf[11]=='1'?Alarm:Normal, NULL);
				d->OverTemperature.value.str					= buf[13]=='1'?"告警":"正常";
				Set_Var_Status(&d->OverTemperature,		  		  buf[13]=='1'?Alarm:Normal, NULL);
				d->ChargerFail.value.str						= buf[14]=='1'?"告警":"正常";
				Set_Var_Status(&d->ChargerFail,		  			  buf[14]=='1'?Alarm:Normal, NULL);
				d->L1IPFuseFail.value.str						= buf[16]=='1'?"告警":"正常";
				Set_Var_Status(&d->L1IPFuseFail,		  		  buf[16]=='1'?Alarm:Normal, NULL);
				d->L2IPFuseFail.value.str						= buf[17]=='1'?"告警":"正常";
				Set_Var_Status(&d->L2IPFuseFail,		  		  buf[17]=='1'?Alarm:Normal, NULL);
				d->L3IPFuseFail.value.str						= buf[18]=='1'?"告警":"正常";
				Set_Var_Status(&d->L3IPFuseFail,		  		  buf[18]=='1'?Alarm:Normal, NULL);
				d->CANCommunicationError.value.str				= buf[25]=='1'?"告警":"正常";
				Set_Var_Status(&d->CANCommunicationError,		  buf[25]=='1'?Alarm:Normal, NULL);
				d->BatteryFuseBroken.value.str					= buf[53]=='1'?"告警":"正常";
				Set_Var_Status(&d->BatteryFuseBroken,		  	  buf[53]=='1'?Alarm:Normal, NULL);
				d->P1CutOffPreAlarm.value.str					= buf[55]=='1'?"告警":"正常";
				Set_Var_Status(&d->P1CutOffPreAlarm,			  buf[55]=='1'?Alarm:Normal, NULL);
				d->BatteryReplaceWarn.value.str					= buf[56]=='1'?"告警":"正常";
				Set_Var_Status(&d->BatteryReplaceWarn,			  buf[56]=='1'?Alarm:Normal, NULL);
				d->MaintainBypassSwitchOffAlarm.value.str		= buf[58]=='1'?"告警":"正常";
				Set_Var_Status(&d->MaintainBypassSwitchOffAlarm,  buf[58]=='1'?Alarm:Normal, NULL);
				d->MainsFailure.value.str						= buf[60]=='1'?"告警":"正常";
				Set_Var_Status(&d->MainsFailure,		  		  buf[60]=='1'?Alarm:Normal, NULL);
				d->BypassUnstable.value.str						= buf[61]=='1'?"告警":"正常";
				Set_Var_Status(&d->BypassUnstable,		  		  buf[61]=='1'?Alarm:Normal, NULL);
				d->BatteryDischargerOverly.value.str			= buf[64]=='1'?"告警":"正常";
				Set_Var_Status(&d->BatteryDischargerOverly,		  buf[64]=='1'?Alarm:Normal, NULL);
				break;
			default:
				break;
		}
		return 0;
	}
	return 1;
}


/**********************************************************************************************************
* 函数名称： void ups_SNHXXX_Registration(void)
* 函数说明： UPS监测驱动注册
* 输入参数： 无
* 返回参数： 无
**********************************************************************************************************/
void ups_SNHXXX_Registration(void)
{
	DeviceDriverRegistration(
		"ups",													//设备类型
		"UPS监测",												//设备名称（导航栏默认显示名称）
		"赛能",													//设备品牌
		"SNHXXX",												//设备型号
		"适用于SNH系列三进单出高频在线式UPS，具备完善的检测、保护功能;体积小、重量轻、工作效率高。协议指令为QGS、QWS、QMOD",//驱动描述
		var_attr,												//变量属性声明
		sizeof(Data_Struct),									//变量结构体空间大小
		cmd_fun,												//发送指令生成函数
		parse_fun,												//数据解析函数
		1000													//设备响应超时时间
	);
#if 0 || VirtualFrameEN
	#define	CMD1	"QWS\r"
	#define	RSP1	"(1111111111111111111111111111111111111111111111111111111111111111\r"
	#define	CMD2	"QMOD\r"
	#define	RSP2	"(C\r"
	#define	CMD3	"QGS\r"
	#define	RSP3	"(231.3 50.0 220.1 50.0 009.8 005 367.2 369.3 214.6 214.4 002.8 100000000000\r"		

	VirtualFrameRegistration(CMD1, sizeof(CMD1)-1, RSP1, sizeof(RSP1)-1);
	VirtualFrameRegistration(CMD2, sizeof(CMD2)-1, RSP2, sizeof(RSP2)-1);
	VirtualFrameRegistration(CMD3, sizeof(CMD3)-1, RSP3, sizeof(RSP3)-1);
#endif		
}

